package com.citycloud.ccuap.tc.admin.interceptor;

import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.citycloud.ccuap.tc.admin.constant.AdminConstant;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.citycloud.ccuap.commons.application.Application;
import com.citycloud.ccuap.commons.json.JSONUtil;
import com.citycloud.ccuap.commons.log.LogHelper;
import com.citycloud.ccuap.commons.model.ISysFunction;
import com.citycloud.ccuap.commons.openapi.interceptor.InterceptorHelper;
import com.citycloud.ccuap.commons.pac4j.Pac4jUtil;
import com.citycloud.ccuap.commons.sys.entity.SysFunction;
import com.citycloud.ccuap.commons.sys.function.IFunctionService;
import com.citycloud.ccuap.commons.web.config.WebGlobalNames;
import com.citycloud.ccuap.commons.web.session.CurrentUser;
import com.citycloud.ccuap.commons.web.session.SessionConstant;
import com.citycloud.ccuap.commons.web.util.ResolveRequest;

@Component
public class BizLogInterceptor implements HandlerInterceptor {
	/** 日志处理 */
	protected static LogHelper logger = new LogHelper(BizLogInterceptor.class);

	private static final String REQUEST_PREFIX = "/error";
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {

		logger.debug("BizLogInterceptor afterCompletion...");
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

		logger.debug("BizLogInterceptor postHandle...");
	}

	private CurrentUser getCurrentUser(HttpServletRequest request) {
		HttpSession session = request.getSession();
		CurrentUser currentUser = (CurrentUser) session.getAttribute(SessionConstant.CURRENT_USER_KEY);
		if (currentUser == null) {
			String token = request.getHeader(SessionConstant.CCUAP_ACCESS_TOKEN_KEY);
			if (!StringUtils.isEmpty(token)) {
				SessionRepository sessionRepository = Application.getClassBean(SessionRepository.class);
				Session sessionMap = sessionRepository.findById(token);
				currentUser = (CurrentUser) sessionMap.getAttribute(SessionConstant.CURRENT_USER_KEY);
			}
		}

		return currentUser;
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		String requestAction = request.getServletPath();
		logger.debug("你的当前请求地址：" + requestAction);
		if (REQUEST_PREFIX.equals(requestAction)) {
			String jsonString = JSONUtil.getErrorJSONString("你的当前请求地址不存在！");
			InterceptorHelper.wirteJsonToResponsee(jsonString, response);
			return false;
		}

		CurrentUser currentUser = getCurrentUser(request);
		if (currentUser == null) {
			String errorMessage = "你还没有登录，请先登录！";
			logger.info(errorMessage);
			String url = Pac4jUtil.getRedirectionUrl(WebGlobalNames.LOGON_PAGE, request);
			String jsonString = JSONUtil.getErrorJSONString(errorMessage, url);
			InterceptorHelper.wirteJsonToResponsee(jsonString, response);
			return false;
		}

		ISysFunction cuFunction = getFunction(requestAction);
		if (cuFunction != null && cuFunction.getLogFlag() == 1) {
			// 记录日志
			String data = ResolveRequest.getParameters(request);
			logger.info("========##=====提交数据(业务日志)：" + data);

			currentUser.setFunction(cuFunction);
			logger.doBizLog(currentUser, "业务日志", data, requestAction);
		}

		return true;
	}

	private SysFunction getFunction(String requestAction) {
		IFunctionService functionService = Application.getClassBean(IFunctionService.class);
		List<SysFunction> functionList = functionService.findAll();

		return functionList.stream().filter(function -> {
			String location = function.getLocation();
			if (location != null && location.indexOf(AdminConstant.STR_QUESTION_MARK) > 0) {
				location = location.substring(0, location.indexOf("?"));
			}

			return requestAction.equals(location);
		}).findFirst().orElse(null);
	}

}
